package com.dwjm.exam.stu_list;

import com.dwjm.utils.ConnectionDatabaseForMySQLUseJdbc;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 学生信息数据访问实现类，实现了 InquireDao 接口，
 * 负责与数据库进行交互，执行学生信息相关的增删改查操作。
 */
public class InquireDaolmpl implements InquireDao {
    // 数据库连接对象
    private Connection connection = null;
    // 预编译语句对象，用于执行 SQL 语句
    private PreparedStatement pstmt = null;
    // 结果集对象，用于存储查询结果
    private ResultSet rs = null;

    /**
     * 构造方法，用于获取数据库连接。
     * 通过 ConnectionDatabaseForMySQLUseJdbc 工具类获取连接，
     * 并将其赋值给 connection 成员变量。
     */
    public InquireDaolmpl() {
        connection = ConnectionDatabaseForMySQLUseJdbc.getConnection();
    }

    /**
     * 向数据库中添加学生信息。
     * @param student 要添加的学生对象
     * @return 执行插入操作影响的行数，成功返回大于 0 的数，失败返回 0
     */
    @Override
    public int addStudent(Student student) {
        // SQL 插入语句，指定要插入的表字段和占位符
        String sql = "INSERT INTO student (studentId, name, gender, birthDate, idCard, college, major, " +
                "className, status, dormId, bedNumber, phone, email, emergencyContact, username, password) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 为预编译语句的占位符设置参数值，对应学生对象的属性
            pstmt.setString(1, student.getStudentId());
            pstmt.setString(2, student.getName());
            pstmt.setString(3, student.getGender());
            // 将 Java.util.Date 转换为 java.sql.Date 并设置参数
            pstmt.setDate(4, new java.sql.Date(student.getBirthDate().getTime()));
            pstmt.setString(5, student.getIdCard());
            pstmt.setString(6, student.getCollege());
            pstmt.setString(7, student.getMajor());
            pstmt.setString(8, student.getClassName());
            pstmt.setString(9, student.getStatus());
            pstmt.setString(10, student.getDormId());
            pstmt.setString(11, student.getBedNumber());
            pstmt.setString(12, student.getPhone());
            pstmt.setString(13, student.getEmail());
            pstmt.setString(14, student.getEmergencyContact());
            pstmt.setString(15, student.getUsername());
            pstmt.setString(16, student.getPassword());
            // 执行插入操作并返回影响的行数
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        } finally {
            // 关闭相关资源
            closeResources();
        }
    }

    /**
     * 根据学生 ID 从数据库中删除学生信息。
     * @param studentId 要删除的学生的 ID
     * @return 执行删除操作影响的行数，成功返回大于 0 的数，失败返回 0
     */
    @Override
    public int deleteStudent(String studentId) {
        // SQL 删除语句，指定删除条件
        String sql = "DELETE FROM student WHERE studentId = ?";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 为预编译语句的占位符设置参数值
            pstmt.setString(1, studentId);
            // 执行删除操作并返回影响的行数
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        } finally {
            // 关闭相关资源
            closeResources();
        }
    }

    /**
     * 更新数据库中学生的信息。
     * @param student 包含更新后信息的学生对象
     * @return 执行更新操作影响的行数，成功返回大于 0 的数，失败返回 0
     */
    @Override
    public int updateStudent(Student student) {
        // SQL 更新语句，指定要更新的字段和更新条件
        String sql = "UPDATE student SET name=?, gender=?, birthDate=?, idCard=?, college=?, major=?, " +
                "className=?, status=?, dormId=?, bedNumber=?, phone=?, email=?, emergencyContact=?, " +
                "username=?, password=? WHERE studentId=?";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 为预编译语句的占位符设置参数值，对应学生对象的属性
            pstmt.setString(1, student.getName());
            pstmt.setString(2, student.getGender());
            pstmt.setDate(3, new java.sql.Date(student.getBirthDate().getTime()));
            pstmt.setString(4, student.getIdCard());
            pstmt.setString(5, student.getCollege());
            pstmt.setString(6, student.getMajor());
            pstmt.setString(7, student.getClassName());
            pstmt.setString(8, student.getStatus());
            pstmt.setString(9, student.getDormId());
            pstmt.setString(10, student.getBedNumber());
            pstmt.setString(11, student.getPhone());
            pstmt.setString(12, student.getEmail());
            pstmt.setString(13, student.getEmergencyContact());
            pstmt.setString(14, student.getUsername());
            pstmt.setString(15, student.getPassword());
            pstmt.setString(16, student.getStudentId());
            // 执行更新操作并返回影响的行数
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        } finally {
            // 关闭相关资源
            closeResources();
        }
    }

    /**
     * 根据学生 ID 从数据库中查询学生信息。
     * @param studentId 要查询的学生的 ID
     * @return 对应的学生对象，如果未找到则返回 null
     */
    @Override
    public Student getStudentById(String studentId) {
        // SQL 查询语句，指定查询条件
        String sql = "SELECT * FROM student WHERE studentId = ?";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 为预编译语句的占位符设置参数值
            pstmt.setString(1, studentId);
            // 执行查询操作，获取结果集
            rs = pstmt.executeQuery();
            if (rs.next()) {
                // 如果结果集有数据，从结果集中提取学生信息并封装为 Student 对象返回
                return extractStudentFromResultSet(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭相关资源
            closeResources();
        }
        return null;
    }

    /**
     * 从数据库中查询所有学生信息。
     * @return 包含所有学生对象的列表，如果没有学生信息则返回空列表
     */
    @Override
    public List<Student> getAllStudents() {
        // 创建用于存储学生对象的列表
        List<Student> students = new ArrayList<>();
        // SQL 查询语句，查询所有学生信息
        String sql = "SELECT * FROM student";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 执行查询操作，获取结果集
            rs = pstmt.executeQuery();
            while (rs.next()) {
                // 遍历结果集，将每条记录提取为学生对象并添加到列表中
                students.add(extractStudentFromResultSet(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭相关资源
            closeResources();
        }
        return students;
    }

    /**
     * 根据给定条件（姓名、学院、专业模糊匹配）从数据库中查询学生信息。
     * @param condition 搜索关键词
     * @return 包含符合条件的学生对象的列表，如果没有符合条件的学生则返回空列表
     */
    @Override
    public List<Student> queryStudents(String condition) {
        // 创建用于存储学生对象的列表
        List<Student> students = new ArrayList<>();
        // SQL 查询语句，指定模糊查询条件
        String sql = "SELECT * FROM student WHERE name LIKE ? OR college LIKE ? OR major LIKE ?";
        try {
            // 创建预编译语句对象
            pstmt = connection.prepareStatement(sql);
            // 构造模糊查询的通配符模式
            String searchPattern = "%" + condition + "%";
            // 为预编译语句的占位符设置参数值
            pstmt.setString(1, searchPattern);
            pstmt.setString(2, searchPattern);
            pstmt.setString(3, searchPattern);
            // 执行查询操作，获取结果集
            rs = pstmt.executeQuery();
            while (rs.next()) {
                // 遍历结果集，将每条记录提取为学生对象并添加到列表中
                students.add(extractStudentFromResultSet(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭相关资源
            closeResources();
        }
        return students;
    }

    /**
     * 从结果集中提取学生信息并封装为 Student 对象。
     * @param rs 数据库查询结果集
     * @return 封装了学生信息的 Student 对象
     * @throws SQLException 如果在从结果集获取数据时出现 SQL 异常
     */
    private Student extractStudentFromResultSet(ResultSet rs) throws SQLException {
        // 创建一个新的 Student 对象
        Student student = new Student();
        // 从结果集中获取各字段值并设置到 Student 对象的对应属性中
        student.setStudentId(rs.getString("studentId"));
        student.setName(rs.getString("name"));
        student.setGender(rs.getString("gender"));
        student.setBirthDate(rs.getDate("birthDate"));
        student.setIdCard(rs.getString("idCard"));
        student.setCollege(rs.getString("college"));
        student.setMajor(rs.getString("major"));
        student.setClassName(rs.getString("className"));
        student.setStatus(rs.getString("status"));
        student.setDormId(rs.getString("dormId"));
        student.setBedNumber(rs.getString("bedNumber"));
        student.setPhone(rs.getString("phone"));
        student.setEmail(rs.getString("email"));
        student.setEmergencyContact(rs.getString("emergencyContact"));
        student.setUsername(rs.getString("username"));
        student.setPassword(rs.getString("password"));
        return student;
    }

    /**
     * 关闭结果集和预编译语句对象，释放相关资源。
     */
    private void closeResources() {
        try {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}